using System;
using System.Text;
using Com.ContentRendering.Api.ParserEngine.Exceptions;

namespace Com.ContentRendering.Api.ParserEngine.State
{
    /// <summary/>
    internal class ParentTagState : AbstractState
    {
        private int _level;

        /// <summary/>
        internal ParentTagState(AbstractState state) : base(state) 
        {
            this._level = Constant.DEFAULT_PARENT_LEVEL;
        }

        /// <summary/>
        protected sealed override void ParseEscapeCharacter()
        {
            throw new TagNameInvalidException();
        }

        /// <summary/>
        protected sealed override void ParseStartCharacter()
        {
            throw new TagNameInvalidException();
        }

        /// <summary/>
        protected sealed override void ParseEndCharacter()
        {
            // append the output tag from the concrete class
            base._outputNode.AddParentOutputTag(this._level);

            // the state needs to be updated
            base._documentParser.State = new ContentState(this);
        }

        /// <summary/>
        protected sealed override void ParseSubstitutionCharacter()
        {
            // append the output tag from the concrete class
            base._outputNode = base._outputNode.AddParentSubstitutionTag(this._level);

            // the state needs to be updated
            base._documentParser.State = new ContentState(this);
        }

        /// <summary/>
        protected sealed override void ParseTransparentCharacter()
        {
            // append the output tag from the concrete class
            base._outputNode = base._outputNode.AddParentTransparentTag(this._level);

            // the state needs to be updated
            base._documentParser.State = new ContentState(this);
        }

        /// <summary/>
        protected sealed override void ParseIfCharacter()
        {
            // append the output tag from the concrete class
            base._outputNode = base._outputNode.AddParentIfTag(this._level);

            // the state needs to be updated
            base._documentParser.State = new ContentState(this);
        }

        /// <summary/>
        protected sealed override void ParseIfNotCharacter()
        {
            // append the output tag from the concrete class
            base._outputNode = base._outputNode.AddParentIfNotTag(this._level);

            // the state needs to be updated
            base._documentParser.State = new ContentState(this);
        }

        /// <summary/>
        protected sealed override void ParseOtherCharacter(char value)
        {
            throw new ParentTagCannotHaveNameException();
        }

        /// <summary/>
        protected override void ParseChildCharacter()
        {
            throw new TagNameInvalidException();
        }

        /// <summary/>
        protected override void ParseParentCharacter()
        {
            // move the level up by one
            this._level++;
        }

        /// <summary/>
        protected sealed override void EndHandler()
        {
            throw new MissingEndCharacterException();
        }
    }
}
